package com.demo.shardingsphere.user.config;

import com.alibaba.druid.pool.DruidDataSource;
import com.demo.shardingsphere.user.config.rule.DbConfig;
import com.demo.shardingsphere.user.config.rule.IShardingService;
import org.apache.shardingsphere.api.config.sharding.ShardingRuleConfiguration;
import org.apache.shardingsphere.api.config.sharding.TableRuleConfiguration;
import org.apache.shardingsphere.api.config.sharding.strategy.StandardShardingStrategyConfiguration;
import org.apache.shardingsphere.shardingjdbc.api.ShardingDataSourceFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.sql.DataSource;
import java.sql.SQLException;
import java.util.*;

/**
 * 分库分表配置
 */
@Configuration
public class UserShardingConfig {
    @Autowired
    private IShardingService shardingService;
    @Bean
    public DataSource shardingCustomer() throws SQLException {

        ShardingRuleConfiguration shardingRuleConfig = new ShardingRuleConfiguration();

        //  配置多数据源
        Map<String, DataSource> dataSourceMap = getDatasourceMap();
        //  其它配置信息
        Properties properties = new Properties();
        // 打印出分库路由后的sql
        properties.setProperty("sql.show", "true");

        //  (分库分表)策略配置
        List<TableRuleConfiguration> allTableRuleConfiguration = getAllTableRuleConfiguration();

        shardingRuleConfig.getTableRuleConfigs().addAll(allTableRuleConfiguration);
        //   创建并返回sharding总数据源,注入容器
        return ShardingDataSourceFactory.createDataSource(dataSourceMap, shardingRuleConfig, properties);
    }


    private List<TableRuleConfiguration> getAllTableRuleConfiguration() {
        List<TableRuleConfiguration> list = new ArrayList<>(8);
        //用户id分表订单表配置
        TableRuleConfiguration userIdRule = getUserTableRuleConfiguration();

        list.add(userIdRule);

        return list;
    }

    /**
     *  商户id 分库分表规则配置
     * @return
     */
    private TableRuleConfiguration getUserTableRuleConfiguration() {
        //  逻辑表名 t_order$
        String nodes = "g01_db_0.t_user${0..3},g01_db_1.t_user${4..6},g01_db_2.t_user${7..9},g02_db_0.t_user${10..12},g02_db_1.t_user${13..15},g02_db_2.t_user${16..18}";
        //表规则配置
        TableRuleConfiguration staffTableRuleConfig = new TableRuleConfiguration("t_user", nodes);
        //数据库分片
        staffTableRuleConfig.setDatabaseShardingStrategyConfig(
                new StandardShardingStrategyConfiguration("user_id", new UserDatabaseAlgorithm()));
        //表分片
        StandardShardingStrategyConfiguration standardShardingStrategyConfiguration = new StandardShardingStrategyConfiguration(
                "user_id", new UserTableAlgorithm());
        staffTableRuleConfig.setTableShardingStrategyConfig(standardShardingStrategyConfiguration);

        return staffTableRuleConfig;
    }

    public   Map<String, DataSource> getDatasourceMap() {

        // 真实数据源map
        Map<String, DataSource> dataSourceMap = new HashMap<>(4);
        try {
            List<DbConfig>    dbConfigList = shardingService.getDbConfigList();
            for(DbConfig dbConfig:dbConfigList){
                DruidDataSource dataSourceDefault = new DruidDataSource();
                dataSourceDefault.setDriverClassName(dbConfig.getDriverClassName());
                dataSourceDefault.setUrl(dbConfig.getUrl() );
                dataSourceDefault.setUsername(dbConfig.getUsername());
                dataSourceDefault.setPassword(dbConfig.getPassword());
                dataSourceMap.put(dbConfig.getDbName(), dataSourceDefault);
            }
        } catch (SQLException e) {
            throw new RuntimeException("dataSourceMap",e);

        }
        return dataSourceMap;
    }

}